# -*- coding: utf-8

import xml.sax
import xml.sax.handler

import readzip
import data
from mylog import logger, set_debug_mode

class tagEventHandler(object):
  def __init__(self):
    pass

  def startElement(self, attr, _obj):
    pass
  
  def endElement(self, _obj):
    pass

  def characters(self, content, _obj):
    pass

class XmindHandler( xml.sax.handler.ContentHandler ):
  """content handler for Xmind content.xml
  """

  def __init__(self, *args, **kwargs):
    self.stack = []
    self.items = data.Items()
    self.topicstack = []

    xml.sax.handler.ContentHandler.__init__( self, *args, **kwargs )
  
  def startDocument(self):
    logger.debug( "[startDocument] Let's get started: " )

  def endDocument(self):
    logger.debug(  "[endDocument] Fin!" )

  def startElement(self, name, attrs):
    if self.taghandlers.has_key(name):
      self.taghandlers[name].startElement(attrs, self)

    self.stack.append(name)

  def endElement(self, name):
    last = self.stack.pop()
    if last != name:
      logger.warning( "Invalid tag %s != %s" % (last, name))
      self.stack.append(last)
    else:
      if self.taghandlers.has_key(name):
        self.taghandlers[name].endElement(self)

  def characters(self, content):
    tag = self.stack[-1]
    if self.taghandlers.has_key(tag):
      self.taghandlers[tag].characters(content, self)

  def get_result(self):
    return self.items

  def tagFrame(self, n):
    return tuple(self.stack[-n:])

  #
  # event handlers for tags
  #
  class tagTopics(tagEventHandler):
    def startElement(dmy, attrs, self):
      pass
    def endElement(dmy, self):
      pass

  class tagTopic(tagEventHandler):
    def startElement(dmy, attrs, self):
      item = data.Item()
      try:
        item.id = attrs.get( u'id' )
      except KeyError:
        pass
      self.topicstack.append( item )
  
    def endElement(dmy, self):
      p = self.topicstack.pop()
      if p.IsTodoTopic():
        self.items.append( p )
  
  class tagMarker(tagEventHandler):
    PRIORITY_LIST = {
      u'priority-1': 1,
      u'priority-2': 2,
      u'priority-3': 3,
      u'priority-4': 4,
      u'priority-5': 5,
      u'priority-6': 6,
    }
    
    PROGRESS_LIST = {
      u'task-start'  : 1,
      u'task-quarter': 25,
      u'task-half'   : 50,
      u'task-3quar'  : 75,
      u'task-done'   : 100,
      u'task-pause'  : data.PAUSE,
    }

    def startElement(me, attrs, self):
      try:
        # check parent
        frame = self.tagFrame(2)
        if frame == (u'topic', u'marker-refs' ):
          topic = self.topicstack[-1]
          marker = attrs.get( u'marker-id' )
          
          if marker in me.PRIORITY_LIST.keys():
            topic.priority = me.PRIORITY_LIST[marker]
          if marker in me.PROGRESS_LIST.keys():
            topic.progress = me.PROGRESS_LIST[marker]
      except KeyError:
        return

  class tagTitle(tagEventHandler):
    def characters(dmy, content, self):
      u = self.tagFrame(2)[0]
      if u == u'topic':
        self.topicstack[-1].title = content

  class tagPlainNote(tagEventHandler):
    def characters(dmy, content, self):
      u = self.tagFrame(3)[0]
      if u == (u'topic', u'notes', u'plain' ):
        self.topicstack[-1].note = content

  taghandlers = {
    'topic' : tagTopic(),
    'marker-ref' : tagMarker(),
    'title' : tagTitle(),
    'plain' : tagPlainNote(),
  }


def parse_xmind(filename):
  handler = XmindHandler()
  
  stream = readzip.open_xmind( filename )
  xml.sax.parse( stream, handler )
  
  return handler.get_result()

if __name__=='__main__':
  set_debug_mode()

  r = parse_xmind( 'design.xmind' )
  logger.debug( "Total ToDo: %d" % (len(r),) )
  for item in r:
    logger.debug( item )

